#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
    int n;
    std::cin >> n;

    std::vector<int> arr; // 存储分解的自然数
    long long s = 0;      // 当前序列和
    int i = 2;            // 从2开始连续取自然数

    // 构建初始序列：连续加入自然数，直到和大于等于n
    while (s < n)
    {
        arr.push_back(i);
        s += i;
        i++;
    }

    long long d = s - n; // 计算差值
    if (d == 1)
    {
        // 删除2，并将最后一个数加1
        arr.erase(std::remove(arr.begin(), arr.end(), 2), arr.end()); // erase–remove 惯用法重点注意
        arr.back() += 1;
    }
    else if (d >= 2)
    {
        // 直接删除d
        arr.erase(std::remove(arr.begin(), arr.end(), d), arr.end());
    }

    // 输出分解方案
    for (size_t j = 0; j < arr.size(); ++j)
    {
        std::cout << arr[j];
        if (j < arr.size() - 1)
            std::cout << " ";
    }
    std::cout << std::endl;

    // 高精度计算乘积
    if (arr.empty())
    {
        // 如果序列为空（理论上不会发生）
        std::cout << 0 << std::endl;
        return 0;
    }

    // 初始化乘积为1（大数，低位在前）
    std::vector<int> result = {1};

    for (int num : arr)
    {
        long long carry = 0;
        // 大数乘以当前数
        for (size_t j = 0; j < result.size(); ++j)
        {
            long long temp = static_cast<long long>(result[j]) * num + carry;
            result[j] = temp % 10;
            carry = temp / 10;
        }
        // 处理剩余进位
        while (carry)
        {
            result.push_back(carry % 10);
            carry /= 10;
        }
    }

    // 将结果转换为字符串（高位在前）
    std::string product_str;
    for (int x : std::vector<int>(result.rbegin(), result.rend()))
    {
        product_str += std::to_string(x);
    }

    std::cout << product_str << std::endl;

    return 0;
}